// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.
#![allow(rustdoc::redundant_explicit_links)]
#![allow(rustdoc::broken_intra_doc_links)]

/// Implements a client for the BigQuery Reservation API.
///
/// # Example
/// ```
/// # tokio_test::block_on(async {
/// # use google_cloud_bigquery_reservation_v1::client::ReservationService;
/// let client = ReservationService::builder().build().await?;
/// // use `client` to make requests to the BigQuery Reservation API.
/// # gax::client_builder::Result::<()>::Ok(()) });
/// ```
///
/// # Service Description
///
/// This API allows users to manage their BigQuery reservations.
///
/// A reservation provides computational resource guarantees, in the form of
/// [slots](https://cloud.google.com/bigquery/docs/slots), to users. A slot is a
/// unit of computational power in BigQuery, and serves as the basic unit of
/// parallelism. In a scan of a multi-partitioned table, a single slot operates
/// on a single partition of the table. A reservation resource exists as a child
/// resource of the admin project and location, e.g.:
/// `projects/myproject/locations/US/reservations/reservationName`.
///
/// A capacity commitment is a way to purchase compute capacity for BigQuery jobs
/// (in the form of slots) with some committed period of usage. A capacity
/// commitment resource exists as a child resource of the admin project and
/// location, e.g.:
/// `projects/myproject/locations/US/capacityCommitments/id`.
///
/// # Configuration
///
/// To configure `ReservationService` use the `with_*` methods in the type returned
/// by [builder()][ReservationService::builder]. The default configuration should
/// work for most applications. Common configuration changes include
///
/// * [with_endpoint()]: by default this client uses the global default endpoint
///   (`https://bigqueryreservation.googleapis.com`). Applications using regional
///   endpoints or running in restricted networks (e.g. a network configured
//    with [Private Google Access with VPC Service Controls]) may want to
///   override this default.
/// * [with_credentials()]: by default this client uses
///   [Application Default Credentials]. Applications using custom
///   authentication may need to override this default.
///
/// [with_endpoint()]: super::builder::reservation_service::ClientBuilder::with_endpoint
/// [with_credentials()]: super::builder::reservation_service::ClientBuilder::credentials
/// [Private Google Access with VPC Service Controls]: https://cloud.google.com/vpc-service-controls/docs/private-connectivity
/// [Application Default Credentials]: https://cloud.google.com/docs/authentication#adc
///
/// # Pooling and Cloning
///
/// `ReservationService` holds a connection pool internally, it is advised to
/// create one and the reuse it.  You do not need to wrap `ReservationService` in
/// an [Rc](std::rc::Rc) or [Arc](std::sync::Arc) to reuse it, because it
/// already uses an `Arc` internally.
#[derive(Clone, Debug)]
pub struct ReservationService {
    inner: std::sync::Arc<dyn super::stub::dynamic::ReservationService>,
}

impl ReservationService {
    /// Returns a builder for [ReservationService].
    ///
    /// ```
    /// # tokio_test::block_on(async {
    /// # use google_cloud_bigquery_reservation_v1::client::ReservationService;
    /// let client = ReservationService::builder().build().await?;
    /// # gax::client_builder::Result::<()>::Ok(()) });
    /// ```
    pub fn builder() -> super::builder::reservation_service::ClientBuilder {
        gax::client_builder::internal::new_builder(
            super::builder::reservation_service::client::Factory,
        )
    }

    /// Creates a new client from the provided stub.
    ///
    /// The most common case for calling this function is in tests mocking the
    /// client's behavior.
    pub fn from_stub<T>(stub: T) -> Self
    where
        T: super::stub::ReservationService + 'static,
    {
        Self {
            inner: std::sync::Arc::new(stub),
        }
    }

    pub(crate) async fn new(
        config: gaxi::options::ClientConfig,
    ) -> gax::client_builder::Result<Self> {
        let inner = Self::build_inner(config).await?;
        Ok(Self { inner })
    }

    async fn build_inner(
        conf: gaxi::options::ClientConfig,
    ) -> gax::client_builder::Result<std::sync::Arc<dyn super::stub::dynamic::ReservationService>>
    {
        if gaxi::options::tracing_enabled(&conf) {
            return Ok(std::sync::Arc::new(Self::build_with_tracing(conf).await?));
        }
        Ok(std::sync::Arc::new(Self::build_transport(conf).await?))
    }

    async fn build_transport(
        conf: gaxi::options::ClientConfig,
    ) -> gax::client_builder::Result<impl super::stub::ReservationService> {
        super::transport::ReservationService::new(conf).await
    }

    async fn build_with_tracing(
        conf: gaxi::options::ClientConfig,
    ) -> gax::client_builder::Result<impl super::stub::ReservationService> {
        Self::build_transport(conf)
            .await
            .map(super::tracing::ReservationService::new)
    }

    /// Creates a new reservation resource.
    pub fn create_reservation(&self) -> super::builder::reservation_service::CreateReservation {
        super::builder::reservation_service::CreateReservation::new(self.inner.clone())
    }

    /// Lists all the reservations for the project in the specified location.
    pub fn list_reservations(&self) -> super::builder::reservation_service::ListReservations {
        super::builder::reservation_service::ListReservations::new(self.inner.clone())
    }

    /// Returns information about the reservation.
    pub fn get_reservation(&self) -> super::builder::reservation_service::GetReservation {
        super::builder::reservation_service::GetReservation::new(self.inner.clone())
    }

    /// Deletes a reservation.
    /// Returns `google.rpc.Code.FAILED_PRECONDITION` when reservation has
    /// assignments.
    pub fn delete_reservation(&self) -> super::builder::reservation_service::DeleteReservation {
        super::builder::reservation_service::DeleteReservation::new(self.inner.clone())
    }

    /// Updates an existing reservation resource.
    pub fn update_reservation(&self) -> super::builder::reservation_service::UpdateReservation {
        super::builder::reservation_service::UpdateReservation::new(self.inner.clone())
    }

    /// Fail over a reservation to the secondary location. The operation should be
    /// done in the current secondary location, which will be promoted to the
    /// new primary location for the reservation.
    /// Attempting to failover a reservation in the current primary location will
    /// fail with the error code `google.rpc.Code.FAILED_PRECONDITION`.
    pub fn failover_reservation(&self) -> super::builder::reservation_service::FailoverReservation {
        super::builder::reservation_service::FailoverReservation::new(self.inner.clone())
    }

    /// Creates a new capacity commitment resource.
    pub fn create_capacity_commitment(
        &self,
    ) -> super::builder::reservation_service::CreateCapacityCommitment {
        super::builder::reservation_service::CreateCapacityCommitment::new(self.inner.clone())
    }

    /// Lists all the capacity commitments for the admin project.
    pub fn list_capacity_commitments(
        &self,
    ) -> super::builder::reservation_service::ListCapacityCommitments {
        super::builder::reservation_service::ListCapacityCommitments::new(self.inner.clone())
    }

    /// Returns information about the capacity commitment.
    pub fn get_capacity_commitment(
        &self,
    ) -> super::builder::reservation_service::GetCapacityCommitment {
        super::builder::reservation_service::GetCapacityCommitment::new(self.inner.clone())
    }

    /// Deletes a capacity commitment. Attempting to delete capacity commitment
    /// before its commitment_end_time will fail with the error code
    /// `google.rpc.Code.FAILED_PRECONDITION`.
    pub fn delete_capacity_commitment(
        &self,
    ) -> super::builder::reservation_service::DeleteCapacityCommitment {
        super::builder::reservation_service::DeleteCapacityCommitment::new(self.inner.clone())
    }

    /// Updates an existing capacity commitment.
    ///
    /// Only `plan` and `renewal_plan` fields can be updated.
    ///
    /// Plan can only be changed to a plan of a longer commitment period.
    /// Attempting to change to a plan with shorter commitment period will fail
    /// with the error code `google.rpc.Code.FAILED_PRECONDITION`.
    pub fn update_capacity_commitment(
        &self,
    ) -> super::builder::reservation_service::UpdateCapacityCommitment {
        super::builder::reservation_service::UpdateCapacityCommitment::new(self.inner.clone())
    }

    /// Splits capacity commitment to two commitments of the same plan and
    /// `commitment_end_time`.
    ///
    /// A common use case is to enable downgrading commitments.
    ///
    /// For example, in order to downgrade from 10000 slots to 8000, you might
    /// split a 10000 capacity commitment into commitments of 2000 and 8000. Then,
    /// you delete the first one after the commitment end time passes.
    pub fn split_capacity_commitment(
        &self,
    ) -> super::builder::reservation_service::SplitCapacityCommitment {
        super::builder::reservation_service::SplitCapacityCommitment::new(self.inner.clone())
    }

    /// Merges capacity commitments of the same plan into a single commitment.
    ///
    /// The resulting capacity commitment has the greater commitment_end_time
    /// out of the to-be-merged capacity commitments.
    ///
    /// Attempting to merge capacity commitments of different plan will fail
    /// with the error code `google.rpc.Code.FAILED_PRECONDITION`.
    pub fn merge_capacity_commitments(
        &self,
    ) -> super::builder::reservation_service::MergeCapacityCommitments {
        super::builder::reservation_service::MergeCapacityCommitments::new(self.inner.clone())
    }

    /// Creates an assignment object which allows the given project to submit jobs
    /// of a certain type using slots from the specified reservation.
    ///
    /// Currently a
    /// resource (project, folder, organization) can only have one assignment per
    /// each (job_type, location) combination, and that reservation will be used
    /// for all jobs of the matching type.
    ///
    /// Different assignments can be created on different levels of the
    /// projects, folders or organization hierarchy.  During query execution,
    /// the assignment is looked up at the project, folder and organization levels
    /// in that order. The first assignment found is applied to the query.
    ///
    /// When creating assignments, it does not matter if other assignments exist at
    /// higher levels.
    ///
    /// Example:
    ///
    /// * The organization `organizationA` contains two projects, `project1`
    ///   and `project2`.
    /// * Assignments for all three entities (`organizationA`, `project1`, and
    ///   `project2`) could all be created and mapped to the same or different
    ///   reservations.
    ///
    /// "None" assignments represent an absence of the assignment. Projects
    /// assigned to None use on-demand pricing. To create a "None" assignment, use
    /// "none" as a reservation_id in the parent. Example parent:
    /// `projects/myproject/locations/US/reservations/none`.
    ///
    /// Returns `google.rpc.Code.PERMISSION_DENIED` if user does not have
    /// 'bigquery.admin' permissions on the project using the reservation
    /// and the project that owns this reservation.
    ///
    /// Returns `google.rpc.Code.INVALID_ARGUMENT` when location of the assignment
    /// does not match location of the reservation.
    pub fn create_assignment(&self) -> super::builder::reservation_service::CreateAssignment {
        super::builder::reservation_service::CreateAssignment::new(self.inner.clone())
    }

    /// Lists assignments.
    ///
    /// Only explicitly created assignments will be returned.
    ///
    /// Example:
    ///
    /// * Organization `organizationA` contains two projects, `project1` and
    ///   `project2`.
    /// * Reservation `res1` exists and was created previously.
    /// * CreateAssignment was used previously to define the following
    ///   associations between entities and reservations: `<organizationA, res1>`
    ///   and `<project1, res1>`
    ///
    /// In this example, ListAssignments will just return the above two assignments
    /// for reservation `res1`, and no expansion/merge will happen.
    ///
    /// The wildcard "-" can be used for
    /// reservations in the request. In that case all assignments belongs to the
    /// specified project and location will be listed.
    ///
    /// **Note** "-" cannot be used for projects nor locations.
    pub fn list_assignments(&self) -> super::builder::reservation_service::ListAssignments {
        super::builder::reservation_service::ListAssignments::new(self.inner.clone())
    }

    /// Deletes a assignment. No expansion will happen.
    ///
    /// Example:
    ///
    /// * Organization `organizationA` contains two projects, `project1` and
    ///   `project2`.
    /// * Reservation `res1` exists and was created previously.
    /// * CreateAssignment was used previously to define the following
    ///   associations between entities and reservations: `<organizationA, res1>`
    ///   and `<project1, res1>`
    ///
    /// In this example, deletion of the `<organizationA, res1>` assignment won't
    /// affect the other assignment `<project1, res1>`. After said deletion,
    /// queries from `project1` will still use `res1` while queries from
    /// `project2` will switch to use on-demand mode.
    pub fn delete_assignment(&self) -> super::builder::reservation_service::DeleteAssignment {
        super::builder::reservation_service::DeleteAssignment::new(self.inner.clone())
    }

    /// Deprecated: Looks up assignments for a specified resource for a particular
    /// region. If the request is about a project:
    ///
    /// 1. Assignments created on the project will be returned if they exist.
    /// 1. Otherwise assignments created on the closest ancestor will be
    ///    returned.
    /// 1. Assignments for different JobTypes will all be returned.
    ///
    /// The same logic applies if the request is about a folder.
    ///
    /// If the request is about an organization, then assignments created on the
    /// organization will be returned (organization doesn't have ancestors).
    ///
    /// Comparing to ListAssignments, there are some behavior
    /// differences:
    ///
    /// 1. permission on the assignee will be verified in this API.
    /// 1. Hierarchy lookup (project->folder->organization) happens in this API.
    /// 1. Parent here is `projects/*/locations/*`, instead of
    ///    `projects/*/locations/*reservations/*`.
    ///
    /// **Note** "-" cannot be used for projects
    /// nor locations.
    #[deprecated]
    pub fn search_assignments(&self) -> super::builder::reservation_service::SearchAssignments {
        super::builder::reservation_service::SearchAssignments::new(self.inner.clone())
    }

    /// Looks up assignments for a specified resource for a particular region.
    /// If the request is about a project:
    ///
    /// 1. Assignments created on the project will be returned if they exist.
    /// 1. Otherwise assignments created on the closest ancestor will be
    ///    returned.
    /// 1. Assignments for different JobTypes will all be returned.
    ///
    /// The same logic applies if the request is about a folder.
    ///
    /// If the request is about an organization, then assignments created on the
    /// organization will be returned (organization doesn't have ancestors).
    ///
    /// Comparing to ListAssignments, there are some behavior
    /// differences:
    ///
    /// 1. permission on the assignee will be verified in this API.
    /// 1. Hierarchy lookup (project->folder->organization) happens in this API.
    /// 1. Parent here is `projects/*/locations/*`, instead of
    ///    `projects/*/locations/*reservations/*`.
    pub fn search_all_assignments(
        &self,
    ) -> super::builder::reservation_service::SearchAllAssignments {
        super::builder::reservation_service::SearchAllAssignments::new(self.inner.clone())
    }

    /// Moves an assignment under a new reservation.
    ///
    /// This differs from removing an existing assignment and recreating a new one
    /// by providing a transactional change that ensures an assignee always has an
    /// associated reservation.
    pub fn move_assignment(&self) -> super::builder::reservation_service::MoveAssignment {
        super::builder::reservation_service::MoveAssignment::new(self.inner.clone())
    }

    /// Updates an existing assignment.
    ///
    /// Only the `priority` field can be updated.
    pub fn update_assignment(&self) -> super::builder::reservation_service::UpdateAssignment {
        super::builder::reservation_service::UpdateAssignment::new(self.inner.clone())
    }

    /// Retrieves a BI reservation.
    pub fn get_bi_reservation(&self) -> super::builder::reservation_service::GetBiReservation {
        super::builder::reservation_service::GetBiReservation::new(self.inner.clone())
    }

    /// Updates a BI reservation.
    ///
    /// Only fields specified in the `field_mask` are updated.
    ///
    /// A singleton BI reservation always exists with default size 0.
    /// In order to reserve BI capacity it needs to be updated to an amount
    /// greater than 0. In order to release BI capacity reservation size
    /// must be set to 0.
    pub fn update_bi_reservation(
        &self,
    ) -> super::builder::reservation_service::UpdateBiReservation {
        super::builder::reservation_service::UpdateBiReservation::new(self.inner.clone())
    }

    /// Gets the access control policy for a resource.
    /// May return:
    ///
    /// * A`NOT_FOUND` error if the resource doesn't exist or you don't have the
    ///   permission to view it.
    /// * An empty policy if the resource exists but doesn't have a set policy.
    ///
    /// Supported resources are:
    ///
    /// - Reservations
    /// - ReservationAssignments
    ///
    /// To call this method, you must have the following Google IAM permissions:
    ///
    /// - `bigqueryreservation.reservations.getIamPolicy` to get policies on
    ///   reservations.
    pub fn get_iam_policy(&self) -> super::builder::reservation_service::GetIamPolicy {
        super::builder::reservation_service::GetIamPolicy::new(self.inner.clone())
    }

    /// Sets an access control policy for a resource. Replaces any existing
    /// policy.
    ///
    /// Supported resources are:
    ///
    /// - Reservations
    ///
    /// To call this method, you must have the following Google IAM permissions:
    ///
    /// - `bigqueryreservation.reservations.setIamPolicy` to set policies on
    ///   reservations.
    pub fn set_iam_policy(&self) -> super::builder::reservation_service::SetIamPolicy {
        super::builder::reservation_service::SetIamPolicy::new(self.inner.clone())
    }

    /// Gets your permissions on a resource. Returns an empty set of permissions if
    /// the resource doesn't exist.
    ///
    /// Supported resources are:
    ///
    /// - Reservations
    ///
    /// No Google IAM permissions are required to call this method.
    pub fn test_iam_permissions(&self) -> super::builder::reservation_service::TestIamPermissions {
        super::builder::reservation_service::TestIamPermissions::new(self.inner.clone())
    }

    /// Creates a new reservation group.
    pub fn create_reservation_group(
        &self,
    ) -> super::builder::reservation_service::CreateReservationGroup {
        super::builder::reservation_service::CreateReservationGroup::new(self.inner.clone())
    }

    /// Returns information about the reservation group.
    pub fn get_reservation_group(
        &self,
    ) -> super::builder::reservation_service::GetReservationGroup {
        super::builder::reservation_service::GetReservationGroup::new(self.inner.clone())
    }

    /// Deletes a reservation.
    /// Returns `google.rpc.Code.FAILED_PRECONDITION` when reservation has
    /// assignments.
    pub fn delete_reservation_group(
        &self,
    ) -> super::builder::reservation_service::DeleteReservationGroup {
        super::builder::reservation_service::DeleteReservationGroup::new(self.inner.clone())
    }

    /// Lists all the reservation groups for the project in the specified location.
    pub fn list_reservation_groups(
        &self,
    ) -> super::builder::reservation_service::ListReservationGroups {
        super::builder::reservation_service::ListReservationGroups::new(self.inner.clone())
    }
}
